﻿using System;
using System.Collections.Generic;
using System.Linq;
using Kinect.Toolbox.Providers;
using Microsoft.Kinect;
using Microsoft.Practices.Unity;

namespace Kinect.Toolbox.Collectors
{
    public class FrameReadyEventArgs : EventArgs
    {
        public Frame Frame { get; private set; }

        public FrameReadyEventArgs(Frame frame)
        {
            Frame = frame;
        }

    }

    public class FramesCollector
    {
        private readonly int _framesCount;
        private readonly LinkedList<Frame> _frames;
        
        public delegate void FrameReadyHandler(object sender, FrameReadyEventArgs args);
        public event FrameReadyHandler FrameReady;

        public FramesCollector(int framesCount = 20)
        {
            _framesCount = framesCount;
            _frames = new LinkedList<Frame>();
            DependencyFactory.Container.Resolve<IToolboxEvents>().FrameProviderChanging += OnFrameProviderChanging;
            DependencyFactory.Container.Resolve<IToolboxEvents>().FrameProviderChanged += OnFrameProviderChanged;

            DependencyFactory.Container.Resolve<IFrameProvider>().FrameReady += OnFrameReady;
        }

        public IList<Frame> GetFrames()
        {
            return _frames.ToList();
        }

        private void OnFrameProviderChanging(object sender, EventArgs eventArgs)
        {
            DependencyFactory.Container.Resolve<IFrameProvider>().FrameReady -= OnFrameReady;
        }

        private void OnFrameProviderChanged(object sender, EventArgs eventArgs)
        {
            DependencyFactory.Container.Resolve<IFrameProvider>().FrameReady += OnFrameReady;
        }

        private void OnFrameReady(object sender, FrameReadyEventArgs e)
        {
            var frame = e.Frame;

            _frames.AddLast(frame);
            if (_frames.Count == _framesCount)
            {
                _frames.RemoveFirst();
            }

            if (FrameReady != null)
            {
                FrameReady(this, new FrameReadyEventArgs(frame));
            }
        }

    }
}
